#ifndef __THREAD_THREAD_H__
#define __THREAD_THREAD_H__

#include "stdint.h"
#include "list.h"

typedef void (thread_func)(void*);

enum task_status
{
	TASK_READY,
	TASK_RUNNING,
	TASK_BLOCKED,
	TASK_WAITING,
	TASK_HANGING,
	TASK_DIED
};

struct task_pcb
{
	void* stack;
	enum task_status status;
	char name[16];
	uint8_t priority;
	uint8_t ticks;
	uint32_t total_ticks;
	
	struct list_item ready_tag;
	struct list_item all_tag;
	
	void* page;
	uint32_t magic;
};

void thread_init(void);
int8_t thread_create(const char* name, uint8_t priority, thread_func* func, void* arg);
struct task_pcb* running_thread();
void schedule(void);

struct intr_stack
{
	uint32_t intr_num;
	uint32_t edi;
	uint32_t esi;
	uint32_t ebp;
	uint32_t esp_dummy;
	uint32_t ebx;
	uint32_t edx;
	uint32_t ecx;
	uint32_t eax;
	uint32_t gs;
	uint32_t fs;
	uint32_t es;
	uint32_t ds;
	
	uint32_t error_no;
	void* eip;
	uint32_t cs;
	uint32_t eflags;
	void* esp;
	uint32_t ss;
};

struct thread_stack
{
	uint32_t ebp;
	uint32_t ebx;
	uint32_t edi;
	uint32_t esi;
	
	void (*ret)(thread_func*, void*);
	void* unused_ret;
	thread_func* func;
	void* arg;
};

#endif
